package com.lineage.server.model.Instance;

import com.lineage.server.model.L1Character;
import com.lineage.server.model.L1Object;
import com.lineage.server.model.poison.L1DamagePoison;
import com.lineage.server.serverpackets.S_DoActionGFX;
import com.lineage.server.serverpackets.S_MoveCharPacket;
import com.lineage.server.serverpackets.S_NPCPack_Eff;
import com.lineage.server.serverpackets.S_RemoveObject;
import com.lineage.server.serverpackets.S_SkillBrave;
import com.lineage.server.serverpackets.ServerBasePacket;
import com.lineage.server.templates.L1Npc;
import com.lineage.server.thread.GeneralThreadPool;
import com.lineage.server.types.Point;
import com.lineage.server.world.World;
import com.lineage.server.world.WorldQuest;
import java.util.ArrayList;
import java.util.Iterator;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class L1EffectInstance extends L1NpcInstance {
  private static final long serialVersionUID = 1L;
  
  private static final Log _log = LogFactory.getLog(L1EffectInstance.class);
  
  public static final int FW_DAMAGE_INTERVAL = 1650;
  
  public static final int CUBE_INTERVAL = 500;
  
  public static final int CUBE_TIME = 8000;
  
  public static final int OTHER = 500;
  
  private L1EffectType _effectType;
  
  private int _skillId;
  
  public L1EffectInstance(L1Npc template) {
    super(template);
    int npcId = getNpcTemplate().get_npcId();
    switch (npcId) {
      case 81157:
        this._effectType = L1EffectType.isFirewall;
        return;
      case 80149:
        this._effectType = L1EffectType.isCubeBurn;
        return;
      case 80150:
        this._effectType = L1EffectType.isCubeEruption;
        return;
      case 80151:
        this._effectType = L1EffectType.isCubeShock;
        return;
      case 80152:
        this._effectType = L1EffectType.isCubeHarmonize;
        return;
      case 86125:
        GeneralThreadPool.get().schedule(new PoisonTimer(this), 0L);
        return;
    } 
    this._effectType = L1EffectType.isOther;
  }
  
  public L1EffectType effectType() {
    return this._effectType;
  }
  
  public void onPerceive(L1PcInstance perceivedFrom) {
    try {
      if (perceivedFrom.get_showId() != get_showId())
        return; 
      perceivedFrom.addKnownObject((L1Object)this);
      perceivedFrom.sendPackets((ServerBasePacket)new S_NPCPack_Eff(this));
      if (getBraveSpeed() > 0)
        perceivedFrom.sendPackets((ServerBasePacket)new S_SkillBrave(getId(), getBraveSpeed(), 600000)); 
    } catch (Exception e) {
      _log.error(e.getLocalizedMessage(), e);
    } 
  }
  
  public void onAction(L1PcInstance pc) {}
  
  public void setFollowSpeed(L1Character target) {
    if (target != null && target.isInvisble()) {
      deleteMe();
      return;
    } 
    if (target.isDead()) {
      deleteMe();
      return;
    } 
    if (target.getMoveSpeed() != getMoveSpeed())
      setMoveSpeed(target.getMoveSpeed()); 
    if (target.getBraveSpeed() != getBraveSpeed())
      setBraveSpeed(target.getBraveSpeed()); 
  }
  
  public void Follow(L1Character target) {
    try {
      if (target == null) {
        deleteMe();
        return;
      } 
      if (target != null && target.isInvisble()) {
        deleteMe();
        return;
      } 
      if (target.isDead()) {
        deleteMe();
        return;
      } 
      if (!destroyed())
        while (!getLocation().isSamePoint((Point)target.getLocation())) {
          int dir = targetDirection(target.getX(), target.getY());
          if (dir != -1)
            setDirectionMove(dir); 
        }  
    } catch (Exception e) {
      _log.error(e.getLocalizedMessage(), e);
    } 
  }
  
  private void setDirectionMove(int heading) {
    int locx = getX();
    int locy = getY();
    locx += L1Character.HEADING_TABLE_X[heading];
    locy += L1Character.HEADING_TABLE_Y[heading];
    setHeading(heading);
    setX(locx);
    setY(locy);
    broadcastPacketAll((ServerBasePacket)new S_MoveCharPacket(this));
  }
  
  public void deleteMe() {
    try {
      this._destroyed = true;
      if (getInventory() != null)
        getInventory().clearItems(); 
      allTargetClear();
      this._master = null;
      int showid = get_showId();
      if (WorldQuest.get().isQuest(showid))
        WorldQuest.get().remove(showid, this); 
      Iterator<L1PcInstance> iterator = World.get().getRecognizePlayer((L1Object)this).iterator();
      while (iterator.hasNext()) {
        L1PcInstance pc = iterator.next();
        if (pc != null) {
          if (getNpcId() == 86131)
            pc.sendPackets((ServerBasePacket)new S_DoActionGFX(getId(), 11)); 
          pc.removeKnownObject((L1Object)this);
          pc.sendPackets((ServerBasePacket)new S_RemoveObject((L1Object)this));
        } 
      } 
      Iterator<L1Object> iterator2 = World.get().getVisibleObjects((L1Object)this).iterator();
      while (iterator2.hasNext()) {
        L1Object obj = iterator2.next();
        if (obj != null && (obj instanceof L1PcInstance || obj instanceof L1NpcInstance)) {
          L1Character cha = (L1Character)obj;
          ArrayList<L1EffectInstance> effectlist = cha.get_TrueTargetEffectList();
          if (!effectlist.contains(this))
            continue; 
          effectlist.remove(this);
        } 
      } 
      removeAllKnownObjects();
      World.get().removeVisibleObject((L1Object)this);
      World.get().removeObject((L1Object)this);
    } catch (Exception e) {
      _log.error(e.getLocalizedMessage(), e);
    } 
  }
  
  public void setSkillId(int i) {
    this._skillId = i;
  }
  
  public int getSkillId() {
    return this._skillId;
  }
  
  class PoisonTimer implements Runnable {
    private static final int POISON_INTERVAL = 1000;
    
    private L1EffectInstance _effect;
    
    public PoisonTimer(L1EffectInstance effect) {
      this._effect = effect;
    }
    
    public void run() {
      while (!L1EffectInstance.this._destroyed) {
        try {
          Iterator<L1Object> iterator = World.get().getVisibleObjects((L1Object)this._effect, 0).iterator();
          while (iterator.hasNext()) {
            L1Object objects = iterator.next();
            if (!(objects instanceof L1MonsterInstance) && !(objects instanceof com.lineage.server.model.L1GroundInventory)) {
              L1Character cha = (L1Character)objects;
              L1DamagePoison.doInfection(this._effect, cha, 3000, 100);
            } 
          } 
          Thread.sleep(1000L);
        } catch (InterruptedException interruptedException) {}
      } 
    }
  }
}
